package com.woniuxy.web;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.entity.*;
import com.woniuxy.service.DishService;
import com.woniuxy.service.ShopService;
import com.woniuxy.service.UserService;
import com.woniuxy.utils.GUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.woniuxy.utils.GUtils.isEmpty;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@Controller
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private DishService dishService;
    //测试进首页，从indexController进
    @GetMapping({"index","","/"})
    public String toIndex(HttpSession session,Model model){
        //user
        User user = (User) session.getAttribute("user");
        //将查询到的菜品数据存到模板中
        model.addAttribute("dishes",dishService.list());
        model.addAttribute("shops",shopService.list());
        session.setAttribute("user", user);
        return "index";
    }
    //测试进list.html
    @GetMapping("list")
    public String toList(){
        return "list";
    }

    @GetMapping("logout")
    public String logout(HttpSession session){
        session.removeAttribute("user");
        Subject subject = SecurityUtils.getSubject();
        try {

            subject.logout();

        } catch (SessionException ise) {

            ise.printStackTrace();

        }
        return "login";
    }

    @GetMapping("getUser")
    @ResponseBody
    public ResponseEntity getUser(HttpSession session){

        User user = (User) session.getAttribute("user");

        ResponseEntity<User> responseEntity = new ResponseEntity<>();
        if(user!=null){
            responseEntity.setCode(200);
        }else{
            responseEntity.setCode(404);

        }

        responseEntity.setData(user);
        return responseEntity;
    }

    /**
     * 进入登录页面
     * @return
     */
    @GetMapping("login")
    public String login(){
        return "login";
    }

    /**
     * 提交登录，验证账户密码
     * @param account
     * @param password
     * @param model
     * @param session
     * @return
     */
    @PostMapping("login")
    public String login(String account, String password, Model model, String verifyCode,HttpSession session) {
    //todo
        //验证码判断

        String v = (String) session.getAttribute("verifyCode");
        if(!verifyCode.equalsIgnoreCase(v)){
            model.addAttribute("verifyMsg", "验证码错误");
            return "login";
        }
        UsernamePasswordToken token = new UsernamePasswordToken(account, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            User user = userService.getByAccount(account);
            session.removeAttribute("user");
            session.setAttribute("user", user);
            return "redirect:/user/index";
        } catch (UnknownAccountException e) {
            model.addAttribute("accountMsg", "账号不存在");
            subject.getSession().removeAttribute("user");
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("passwordMsg", "密码不正确");
        }


        return "login";
    }

    //进入注册页面
    @GetMapping("register")
    public String register() {
        return "register";
    }

    /**
     * 注册账户，跳转登录页面
     *
     * @return
     */
    @PostMapping("register")
    public String register(String name, String password, String email, Model model,
                           String rePassword,String verifyCode,HttpSession session) {

        //验证码判断
        String v = (String) session.getAttribute("verifyCode");
        if(!verifyCode.equalsIgnoreCase(v)){
            model.addAttribute("verifyMsg", "验证码错误");
            return "register";
        }

        log.debug("name:{},password:{},email:{}", name, password, email);
        //账户重复判断
        User user = userService.getByAccount(name);
        if(user!=null){
            model.addAttribute("nameMsg","账户重复");
            return "register";
        }
        //账号非空判断
        if (isEmpty(name)) {//静态引入
            model.addAttribute("nameMsg", "账号为空");
            return "register";
        }
        //账号长度限定
        if (name.trim().length() < 6 || name.trim().length() > 15) {
            model.addAttribute("nameMsg", "账号长度在6-15之间");

            return "register";
        }
        //密码非空判断
        if (isEmpty(password)) {//静态引入
            model.addAttribute("passwordMsg", "账号为空");
            return "register";
        }
        //密码长度限定
        if (password.trim().length() < 6 || password.trim().length() > 12) {
            model.addAttribute("passwordMsg", "密码长度在6-12之间");

            return "register";
        }
        //判断两次密码是否一致
        if (!password.equals(rePassword)) {
            model.addAttribute("rePasswordMsg", "两次输入密码不一致");
            return "register";
        }
        //判断邮箱是否合法
        if (null == email || "".equals(email)) {

            model.addAttribute("emailMsg", "邮箱不能为空");
            return "register";
        }
        String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern p = Pattern.compile(regEx1);
        Matcher m = p.matcher(email);
        if (!m.matches()) {

            model.addAttribute("emailMsg", "邮箱不合法");
            return "register";
        }
        //对密码进行MD5加密
        String pwd = new SimpleHash("MD5", password, null, 1024).toHex();

        //添加用户注册信息到数据库，返回到登录页面
        userService.register(name, pwd, email);
        return "login";
    }




    /**
     * 生成验证码图片，存入session
     * @param response
     * @param request
     * @param session
     */
    @GetMapping("getVerifyCode")
    public void getVerificationCode(HttpServletResponse response, HttpServletRequest request, HttpSession session) {

        try {

            int width = 200;

            int height = 69;

            BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            //生成对应宽高的初始图片

            String randomText = VerifyCode.drawRandomText(width, height, verifyImg);

            //单独的一个类方法，出于代码复用考虑，进行了封装。

            //功能是生成验证码字符并加上噪点，干扰线，返回值为验证码字符

            request.getSession().setAttribute("verifyCode", randomText);
            session.removeAttribute("verifyCode");
            session.setAttribute("verifyCode",randomText);

            response.setContentType("image/png");//必须设置响应内容类型为图片，否则前台不识别

            OutputStream os = response.getOutputStream(); //获取文件输出流

            ImageIO.write(verifyImg, "png", os);//输出图片流

            os.flush();

            os.close();//关闭流

        } catch (IOException e) {


            e.printStackTrace();

        }

    }


    /**
     * //进入个人中心
     *
     * @return
     */
    @GetMapping("ucenter")
    public String toUCenter(Model model,HttpSession session) {
        User user = (User) session.getAttribute("user");
        model.addAttribute("user",userService.getById(user.getId()));
        return "ucenter/user_center";
    }

    /**
     * 进入账户管理
     * @param model
     * @param session
     * @return
     */
    @GetMapping("account")
    public String toAccount(Model model,HttpSession session) {
        User user = (User) session.getAttribute("user");
        model.addAttribute("user",userService.getById(user.getId()));
        return "ucenter/user_account";
    }

    /**
     * 进入修改密码
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("pswchange")
    public String change(Model model,HttpSession session){

        User user = (User) session.getAttribute("user");
        model.addAttribute("user",userService.getById(user.getId()));
        System.out.println(userService.getById(user.getId()));
        return "ucenter/user_pswchange";
    }

    /**
     * 修改密码
     * @param model
     * @param session
     * @param oldPsw
     * @param newPsw
     * @param cfmPsw
     * @return
     */
    @RequestMapping("updatepsw")
    public String update(Model model,HttpSession session,String oldPsw,String newPsw,String cfmPsw){
        User user = (User) session.getAttribute("user");


        //对原密码进行MD5加密
         oldPsw = new SimpleHash("MD5", oldPsw, null, 1024).toHex();
        //对新密码进行MD5加密
        newPsw = new SimpleHash("MD5", newPsw, null, 1024).toHex();
        //对确认密码进行MD5加密
        cfmPsw = new SimpleHash("MD5", cfmPsw,null, 1024).toHex();


        if(!oldPsw.equals(user.getPassword())){
            model.addAttribute("psgMsg","原密码错误");


            return "ucenter/user_pswchange";
        }
        if(!cfmPsw.equals(newPsw)){
            model.addAttribute("cfgMsg","确认密码与新密码不一致");
            return "ucenter/user_pswchange";
        }

        model.addAttribute("user",userService.getById(user.getId()));
        userService.updatePsw(user.getName(), cfmPsw);
        //登出
        Subject subject = SecurityUtils.getSubject();
        try {

            subject.logout();

        } catch (SessionException ise) {

            ise.printStackTrace();

        }
        return "login";
    }


    @Value("${gfr.images}")
    private String imagePath;

    /**
     * 修改头像，修改昵称，修改邮箱
     * @param session
     * @param file
     * @param model
     * @param req
     * @param name
     * @return
     */
    @RequestMapping("avater")
    public String updateAvater(HttpSession session, MultipartFile file, Model model, HttpServletRequest req,String name){

        if(file!=null){
            log.debug("imagePath:{}",imagePath);
            //创建文件夹
            GUtils.createDirectory();


            User user = (User) session.getAttribute("user");
            log.debug("Name:{}",user.getName());
            //获取上传文件的原名
            file.getOriginalFilename();
            //获得上传文件的后缀
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            //生成新的文件名
            String newFileName = UUID.randomUUID().toString().replace("-", "")+suffix;
            //保存到目标文件中去
            try {

                file.transferTo(new File(imagePath+"\\"+newFileName));
            } catch (IOException e) {
                e.printStackTrace();
            }
            user.setAvater(newFileName);
            userService.update(user);
        }
            String opr = req.getParameter("name");

            if(opr != null && !"".equals(opr)){
                User user = (User) session.getAttribute("user");
                if(userService.getNameCount(opr)>=1){
                    model.addAttribute("nameMsg","该昵称已被占用");
                    return "ucenter/user_account";
                }
                user.setName(name);

                userService.update(user);


            }

            String newMail = req.getParameter("email");
            if(newMail != null && !"".equals(newMail)){
                User user = (User) session.getAttribute("user");
                if(userService.getEmileCount(newMail)>=1){
                    model.addAttribute("emailMsg","该邮箱已经被使用");
                    return "ucenter/user_account";
                }
                user.setEmail(newMail);
                userService.update(user);
            }


        return "redirect:/user/ucenter";
    }

    /**
     * 进入个人收藏
     * @param model
     * @param session
     * @return
     */
    @GetMapping("collect")
    public String toMyCollection(Model model,HttpSession session){
        User user = (User) session.getAttribute("user");
        model.addAttribute("shopes",userService.getShopByUserId(user.getId()));
        return "ucenter/user_favorites";
    }

}


